<?php
/**
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * PHP Version 5
 *
 * @category Shape
 * @author   Wang Zhaogang <Wang Zhaogang@babamaiche.com>
 * @file     Shape.php
 * @date     2016/9/6
 * @time     11:30
 * @license  http://chedamai.cn/ License
 * @link     http://chedamai.cn/
 */
namespace app\components;
/**
 * The Shape class is used for ***
 *
 * @category Shape
 * @author   Wang Zhaogang <Wang Zhaogang@babamaiche.com>
 * @class    Shape
 * @date     2016/9/6
 * @time     11:30
 * @license  http://chedamai.cn/ License
 * @link     http://chedamai.cn/
 */
class Shape
{
    private $width;
    private $height;
    private $color;
    private $data = [];
    private $rotate = 0;
    private $revert = 0;
    private $id = 0;

    private $placement = 0;

    public function nextPlacement() {
        $thePlacement = $this->placement;
        if ($thePlacement >= 2 * 4) {
            return false;
        }
        $this->setRevert(intval($thePlacement / 4));
        $this->setRotate(intval($thePlacement % 4));
        $this->placement++;
        return true;
    }
    public function clearPlacement() {
        $this->placement = 0;
    }
    public function getPlacement() {
        return [
            'placement' => $this->placement,
            'revert' => $this->revert,
            'rotate' => $this->rotate,
        ];
    }
    /**
     * @param int $rotate
     */
    public function setRotate($rotate)
    {
        $this->rotate = $rotate % 4;
    }

    /**
     * @param int $revert
     */
    public function setRevert($revert)
    {
        $this->revert = $revert % 2;
    }

    /**
     * Shape constructor.
     * @param $width
     * @param $height
     * @param array $data
     */
    public function __construct($id, $width, $height, array $data, $color)
    {
        $this->id = $id;
        $this->width = $width;
        $this->height = $height;
        $this->data = $data;
        $this->color = $color;
        $this->rotate = 0;
        $this->revert = 0;
        $this->placement = 0;
    }
    private static function rotate($data, $width, $height) {
        $newData = [];
        $newHeight = $width;
        $newWidth = $height;
        for ($i = 0; $i < $newHeight; $i++) {
            for ($j = 0; $j < $newWidth; $j++) {
                $newData[$i][$j] =
                    $data[$height - $j - 1][$i];
            }
        }
       return [$newData, $newWidth, $newHeight];
    }
    public function toArray() {
        $revertedData = [];
        //反转
        for ($i = 0; $i < $this->height; $i++) {
            for ($j = 0; $j < $this->width; $j++) {
                if ($this->revert === 1) {
                    $revertedData[$i][$j] = $this->data[$i][$this->width - $j - 1];
                } else {
                    $revertedData[$i][$j] = $this->data[$i][$j];
                }
            }
        }
        //旋转
        $finalData = [];
        $tmpData = $revertedData;
        $tmpHeight = $this->height;
        $tmpWidth = $this->width;
        for ($i = 0; $i < $this->rotate; $i++) {
            $rotatedResult = self::rotate($tmpData, $tmpWidth, $tmpHeight);
            $tmpData = $rotatedResult[0];
            $tmpWidth = $rotatedResult[1];
            $tmpHeight = $rotatedResult[2];
        }
        return [
            'width' => $tmpWidth,
            'height' => $tmpHeight,
            'data' => $tmpData,
            'color' => $this->color,
        ];
    }
    public function toHash() {
        return $this->id * 8 + $this->revert * 4 + $this->rotate;
    }
    public function getId() {
        return $this->id;
    }
    public static function formatArray($a) {
        if (!is_array($a) || empty($a)) {
            return "\n";
        }
        $height = count($a);
        $ret = "\n";
        for ($j = 0; $j < $height; $j++) {
            $ret = $ret . implode('', $a[$j]);
            $ret = $ret . "\n";
        }
        return $ret;
    }
}